package com.xbongbong.saas.model.impl;

import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.redis.RedisTimeConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.wrap.EnableApiCallBack;
import com.xbongbong.pro.enums.ApiCallBackEnum;
import com.xbongbong.saas.domain.dao.ProductCategoryDao;
import com.xbongbong.saas.domain.entity.ProductCategoryEntity;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.model.ProductCategoryModel;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @version v1.0
 * @date 2019/3/22 10:11
 * @since v1.0
 */
@Service("productCategoryModel")
public class ProductCategoryModelImpl implements ProductCategoryModel {

    private static final String COLUMN = "id,corpid,parent_id,name, router,sort, add_time,update_time,del,enable_batch_shelf_life,shelf_life_days,expiration_alert_days,enable_serial_number,enable_multi_unit,unit_value";

    @Resource
    private ProductCategoryDao productCategoryDao;
    @Resource
    private PaasRedisHelper paasRedisHelper;

    @Override
    @EnableApiCallBack(callBackBusiness = ApiCallBackEnum.PRODUCT_CATEGORY, operateTypeEnum = OperateTypeEnum.NEW)
    public Integer insert(ProductCategoryEntity entity) throws XbbException {
        long now = DateUtil.getInt();
        entity.setAddTime(now);
        entity.setUpdateTime(now);
        return productCategoryDao.insert(entity);
    }

    @Override
    @EnableApiCallBack(callBackBusiness = ApiCallBackEnum.PRODUCT_CATEGORY, operateTypeEnum = OperateTypeEnum.EDIT)
    public Integer update(ProductCategoryEntity entity) throws XbbException {
        long now = DateUtil.getInt();
        entity.setUpdateTime(now);
        return productCategoryDao.update(entity);
    }

    @Override
    public List<ProductCategoryEntity> findEntitys(Map<String, Object> param) {
        param.put("columns", COLUMN);
        return productCategoryDao.findEntitys(param);
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return productCategoryDao.getEntitysCount(param);
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return null;
    }

    @Override
    @EnableApiCallBack(callBackBusiness = ApiCallBackEnum.PRODUCT_CATEGORY, operateTypeEnum = OperateTypeEnum.EDIT, isBatch = true)
    public Integer updateBatch(List<ProductCategoryEntity> list, String corpid) {
        return productCategoryDao.updateBatch(list, corpid);
    }

    @Override
    public ProductCategoryEntity getByKey(Long key, String corpid) {
        return productCategoryDao.getByKey(key, corpid);
    }

    @Override
    @EnableApiCallBack(callBackBusiness = ApiCallBackEnum.PRODUCT_CATEGORY, operateTypeEnum = OperateTypeEnum.DELETE)
    public Integer delete(Long key, String corpid) {
        return productCategoryDao.deleteByKey(key, corpid);
    }

    /**
     * 获取产品分类信息
     * @param corpid 公司id
     * @param categoryIdIn 分类id数组
     * @return java.util.List<com.xbongbong.saas.domain.entity.ProductCategoryEntity>
     * @author zcp
     * @date 2019/4/8 21:18
     * @since v1.0
     * @version v1.0
     */
    @Override
    public List<ProductCategoryEntity> getProductCategoryListByIdIn(String corpid, Collection<Long> categoryIdIn) {
        if (categoryIdIn == null || categoryIdIn.size() == 0) {
            return new ArrayList<>();
        }
        //查询图表分类的参数
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("idIn", categoryIdIn);
        //产品分类实体列表
        return findEntitys(param);
    }
    /**
     * 通过id列表获取产品分类并构建id和entity的对应关系
     * @param corpid 公司id
     * @param categoryIdIn 分类id数组
     * @return java.util.Map<java.lang.Long,com.xbongbong.saas.domain.entity.ProductCategoryEntity>
     * @author zcp
     * @date 2019/4/8 21:25
     * @since v1.0
     * @version v1.0
     */
    @Override
    public Map<Long, ProductCategoryEntity> getProductCategoryMapByIdIn(String corpid, Collection<Long> categoryIdIn) {
        List<ProductCategoryEntity> categoryList = getProductCategoryListByIdIn(corpid, categoryIdIn);
        //分类id--分类信息
        Map<Long, ProductCategoryEntity> map = new HashMap<>(categoryList.size());
        for (ProductCategoryEntity entity : categoryList) {
            map.put(entity.getId(), entity);
        }
        return map;
    }

    @Override
    public Map<Long, List<ProductCategoryEntity>> getSupSubListMap(List<ProductCategoryEntity> allCategoryList) {
        Map<Long, List<ProductCategoryEntity>> supSubListCategoryMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (allCategoryList == null) {
            return supSubListCategoryMap;
        }
        //分类id-分类实体map
        Map<Long, ProductCategoryEntity> allCategoryMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ProductCategoryEntity entity : allCategoryList) {
            allCategoryMap.put(entity.getId(), entity);
        }
        for (ProductCategoryEntity entity : allCategoryList) {
            Long parentId = entity.getParentId();
            //父级
            ProductCategoryEntity parentEntity = allCategoryMap.get(parentId);
            if (parentEntity == null) {
                continue;
            }

            List<ProductCategoryEntity> value = supSubListCategoryMap.get(parentId);
            if (value == null) {
                value = new ArrayList<>();
            }
            value.add(entity);
            supSubListCategoryMap.put(parentId, value);
        }
        return supSubListCategoryMap;
    }

    @Override
    @EnableApiCallBack(callBackBusiness = ApiCallBackEnum.PRODUCT_CATEGORY, operateTypeEnum = OperateTypeEnum.EDIT)
    public Integer updateToNull(ProductCategoryEntity entity) throws XbbException {
        long now = DateUtil.getInt();
        entity.setUpdateTime(now);
        return productCategoryDao.updateToNull(entity);
    }

    @Override
    public Map<Long,String> categoryList(String corpid) {
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",corpid);
        map.put("del",0);
        Map<Long,String> categoryMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<ProductCategoryEntity> categoryEntityList = findEntitys(map);
        for (ProductCategoryEntity entity : categoryEntityList){
            categoryMap.put(entity.getId(),entity.getName());
        }
        return categoryMap;
    }

    @Override
    public List<ProductCategoryEntity> getSubOneLevel(String corpid, Long categoryId, boolean containSup) {
        List<ProductCategoryEntity> list = new ArrayList<>();
        if (Objects.isNull(categoryId)) {
            return list;
        }
        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        param.put("del", 0);
        if (containSup) {
            param.put("parentAndSub", categoryId);
        } else {
            param.put("parentId", categoryId);
        }
        Integer start = 0;
        //步长
        Integer pageNum = 5000;
        /************查询指标************/
        for(;start <= Integer.MAX_VALUE; start = start + pageNum){
            param.put("start", start);
            param.put("pageNum", pageNum);
            List<ProductCategoryEntity> perList = findEntitys(param);
            list.addAll(perList);
            if (perList.size() < pageNum) {
                break;
            }
        }
        return list;
    }

    @Override
    public List<ProductCategoryEntity> getSubOneLevelFromJedis(String corpid, Long categoryId, boolean containSup) {
        String key = corpid + "_" + categoryId + "_" + containSup;
        String redisCategoryId = paasRedisHelper.getValue(RedisPrefixConstant.SUB_ONE_LEVEL_CATEGORY, key);
        List<ProductCategoryEntity> list = JsonHelperUtil.parseArray(redisCategoryId, ProductCategoryEntity.class);
        if (CollectionUtils.isNotEmpty(list)) {
            return list;
        }
        // 下一级子分类列表
        list = getSubOneLevel(corpid, categoryId, containSup);
        paasRedisHelper.setValue(RedisPrefixConstant.SUB_ONE_LEVEL_CATEGORY, key, list, RedisTimeConstant.TEN_MINUTES);
        return list;
    }
}
